package com.egg.common.translate.config;


import cn.hutool.core.util.ObjectUtil;
import com.alibaba.nacos.api.NacosFactory;
import com.alibaba.nacos.api.PropertyKeyConst;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.listener.Listener;
import com.alibaba.nacos.api.exception.NacosException;
import com.egg.common.core.constant.StringPool;
import com.egg.common.translate.enums.I18nTypeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;


/**
 * 初始化翻译文件
 */
@Slf4j
@Configuration
public class I18nFileConfig {


    /**
     * 默认空间组
     */
    private static final String DEFAULT_GROUP = "DEFAULT_GROUP";


    @Value("${spring.cloud.nacos.config.server-addr}")
    private String serverAddr;
    @Value("${spring.cloud.nacos.config.i18n.namespace}")
    private String namespace;


    /**
     * 初始化NACOS服务， 用于读取翻译文件
     *
     * @return
     * @throws NacosException
     */
    @Bean
    public ConfigService initNacosConfigService() throws NacosException {
        Properties properties = new Properties();
        properties.put(PropertyKeyConst.SERVER_ADDR, serverAddr);
        properties.put(PropertyKeyConst.NAMESPACE, namespace);
        return NacosFactory.createConfigService(properties);
    }

    @Autowired
    private ConfigService configService;


    /**
     * 初始化翻译文件
     */
    @Bean
    public void initFile() throws NacosException {
        List<I18nTypeEnum> languagesTypeList = Arrays.asList(I18nTypeEnum.values());
        for (I18nTypeEnum type : languagesTypeList) {
            String filePath = buildFilePath(type);
            if (ObjectUtil.isEmpty(filePath)) {
                log.error("初始化语言{}文件失败, 由于获取文件目录路径失败", type.getMessage());
                continue;
            }
            String content = configService.getConfig(type.getCode(), "DEFAULT_GROUP", 5000);
            writeFile(filePath, content);
            listener(configService, type, filePath);
        }
    }

    /**
     * 文件保存的目录
     *
     * @return
     */
    public static String getDirectoryPath() {
        try {
            return ResourceUtils.getURL("classpath:").getPath() + "static/i18n/message";
        } catch (FileNotFoundException e) {
            log.error("获取文件保存目录失败", e);
        }
        return "";
    }

    /**
     * 文件保存的完整路径
     *
     * @return
     */
    private static String buildFilePath(I18nTypeEnum type) {
        // 文件只支持 "properties" 文件
        String directoryPath = getDirectoryPath();
        if (ObjectUtil.isEmpty(directoryPath)) {
            return "";
        }
        return directoryPath + StringPool.UNDERSCORE + type.getCode() + ".properties";
    }

    /**
     * 创建监听器
     *
     * @param filePath
     * @return
     */
    private Listener createListener(String filePath) {
        return new Listener() {
            @Override
            public Executor getExecutor() {
                return null;
            }

            @Override
            public void receiveConfigInfo(String configInfo) {
                writeFile(filePath, configInfo);
            }
        };
    }

    /**
     * 写翻译文件
     *
     * @param filePath   完整文件存放地址
     * @param configInfo 文件信息
     */
    private void writeFile(String filePath, String configInfo) {
        try {
            FileUtils.writeStringToFile(new File(filePath), configInfo, StandardCharsets.UTF_8.name());
        } catch (IOException e) {
            log.error("写翻译文件 {} 失败 {}", filePath, e);
        }
    }

    /**
     * 监听变化
     *
     * @param configService nacos服务
     * @param type          监控的语言
     * @param filePath      文件地址
     * @throws NacosException
     */
    private void listener(ConfigService configService, I18nTypeEnum type, String filePath) {
        try {
            configService.addListener(type.getCode(), DEFAULT_GROUP, createListener(filePath));
        } catch (NacosException e) {
            log.error("初始化Nacos监听器{}异常, 原因 {}", type.getMessage(), e.getErrMsg());
        }
    }


}
